package org.kabanyo.components.supportClasses {

	import mx.collections.IList;

	import org.kabanyo.components.IDataSeries;
	import org.kabanyo.components.ISeriesItem;
	import org.kabanyo.components.IToolTipRenderer;

	/**
	 * Handle visualization proses for defined data series.
	 *
	 * @author Desky Natalio
	 *
	 */
	public class DataSeries implements IDataSeries {

		private var _toolTipRenderer:IToolTipRenderer;

		/**
		 * Renderer that is used for tooltip.
		 */
		public function get toolTipRenderer():IToolTipRenderer {
			return _toolTipRenderer;
		}

		/**
		 * @private
		 */
		public function set toolTipRenderer(value:IToolTipRenderer):void {
			_toolTipRenderer=value;
		}

		private var _dataProvider:IList;

		/**
		 * List of data that used by series.
		 */
		public function get dataProvider():IList {
			return _dataProvider;
		}

		/**
		 * @private
		 */
		public function set dataProvider(value:IList):void {
			_dataProvider=value;
		}

		private var _groupFields:Array=[];

		/**
		 * Set of group field from DataProvider.
		 */
		public function get groupFields():Array {
			return _groupFields;
		}

		private var _dataField:String;

		/**
		 * Define data field from DataProvider.
		 */
		public function get dataField():String {
			return _dataField;
		}

		/**
		 * @private
		 */
		public function set dataField(value:String):void {
			_dataField=value;
		}

		private var _labelField:String;

		/**
		 * Define label field from DataProvider.
		 */
		public function get labelField():String {
			return _labelField;
		}

		/**
		 * @private
		 */
		public function set labelField(value:String):void {
			_labelField=value;
		}

		private var _seriesField:String;

		/**
		 * Define series field from DataProvider.
		 */
		public function get seriesField():String {
			return _seriesField;
		}

		/**
		 * @private
		 */
		public function set seriesField(value:String):void {
			_seriesField=value;
		}

		private var seriesName:String;

		/**
		 * Constructor
		 *
		 */
		public function DataSeries() {
			super();
		}

		/**
		 * Add specified field to groupFields array.
		 * Group fields containt fieldName and has defined equal value.
		 *
		 * @param fieldName
		 * @param value
		 *
		 */
		public function addGroupField(fieldName:String, value:Object):void {
			_groupFields.push({key: fieldName, value: value});
		}

		public function removeAllGroupField():void {
			_groupFields=[];
		}

		/**
		 * Transform dataprovider to array of series where each series containt name and values
		 *
		 * @return series item
		 *
		 */
		public function getSeriesItem(seriesName:String, unit:String):ISeriesItem {
			if (!dataProvider && !groupFields) {
				return null;
			}
			var dataArray:Array=dataProvider.toArray().filter(groupFiltering);
			this.seriesName=seriesName;
			var filteredDataArray:Array=dataArray.filter(seriesFiltering);
			var values:Array=[];
			for (var i:int=0; i < filteredDataArray.length; i++) {
				values.push({value: filteredDataArray[i][dataField]});
			}
			var seriesItem:ISeriesItem={name: seriesName, values: values, unit: unit} as ISeriesItem;
			return seriesItem;
		}

		public function getSeriesNames():Array {
			var seriesNames:Array=[];
			var dataArray:Array=dataProvider.toArray().filter(groupFiltering);
			for (var i:int=0; i < dataArray.length; i++) {
				for (var j:int=0; j < seriesNames.length; j++) {
					if (dataArray[i][seriesField] != seriesNames[j]) {
						seriesNames.push(dataArray[i][seriesField]);
					}
				}
			}
			return seriesNames;
		}

		private function groupFiltering(item:Object):Boolean {
			var result:Boolean=false;
			for (var i:int=0; i < groupFields.length; i++) {
				if (item[groupFields[i]["key"]] == groupFields[i]["value"]) {
					result=true;
				} else {
					result=false;
				}
			}
			return result;
		}

		private function seriesFiltering(item:Object):Boolean {
			if (item[seriesField] == seriesName) {
				return true;
			} else {
				return false;
			}
		}
	}
}
